﻿using System;
using System.Collections.ObjectModel;
using System.ComponentModel;
using System.DirectoryServices;
using System.Security;
using System.Security.Permissions;
using AzManPermissions;

namespace AzManApplication
{
  public class MainWindowViewModel : INotifyPropertyChanged
  {
    public MainWindowViewModel()
    {
      Status = "...";
      AzManResults = new ObservableCollection<string>();
    }

    private string status;

    public string Status
    {
      get { return status; }
      set
      {
        if (value != status)
        {
          status = value;
          NotifyOfPropertyChange("Status");
        }
      }
    }

    private string roleName;

    public string RoleName
    {
      get { return roleName; }
      set
      {
        if (value != roleName)
        {
          roleName = value;
          NotifyOfPropertyChange("RoleName");
        }
      }
    }

    private ObservableCollection<string> users;

    public ObservableCollection<string> AzManResults
    {
      get { return users; }
      set
      {
        if (value != users)
        {
          users = value;
          NotifyOfPropertyChange("Users");
        }
      }
    }

    /// <summary>
    /// AzMan operation check imperatively in local process.
    /// </summary>
    public void SomeActionLocal()
    {
      AzManOperationPermission azmanPerm = new AzManOperationPermission(null, (int)Operations.SomeAction);
      try
      {
        azmanPerm.Demand();
        Status = "Demand succeeded";
      }
      catch (SecurityException)
      {
        Status = "Demand failed, access denied";
      }
    }

    /// <summary>
    /// AzMan operation check imperatively in remote WCF service.
    /// </summary>
    public void SomeActionRemote()
    {
      AzManOperationRemotePermission azmanPerm = new AzManOperationRemotePermission(null, (int)Operations.SomeAction);
      try
      {
        azmanPerm.Demand();
        Status = "Demand succeeded";
      }
      catch (SecurityException)
      {
        Status = "Demand failed, access denied";
      }
    }

    /// <summary>
    /// AzMan operation check declaratively in local process.
    /// </summary>
    [AzManOperationPermission(SecurityAction.Demand, Operation = (int)Operations.OtherAction)]
    public void OtherAction()
    {
      Status = "Demand succeeded";
    }

    /// <summary>
    /// AzMan operation check declaratively in remote WCF service.
    /// </summary>
    [AzManOperationRemotePermission(SecurityAction.Demand, Operation = (int)Operations.OtherAction)]
    public void OtherActionRemote()
    {
      Status = "Demand succeeded";
    }

    public void GetUserNames()
    {
      string[] roleUserNames = AzManOperationHelper.MemberNamesInRole(RoleName);
      AzManResults.Clear();
      Array.ForEach(roleUserNames, x => AzManResults.Add(x));
    }

    public void GetUsers()
    {
      string[] roleUsers = AzManOperationHelper.MembersInRole(RoleName);
      AzManResults.Clear();
      Array.ForEach(roleUsers, x => AzManResults.Add(x));
    }

    public void GetAllUsers()
    {
      MemberSearchResult[] roleUsers = AzManOperationHelper.AllMembersInRole(RoleName, new string[] { "mail", "cn" });
      AzManResults.Clear();

      //Array.ForEach(roleUsers, x => AzManResults.Add(string.Format("{0}'s email address: {1}", x.AccountName, x.Properties["mail"].Count == 0 ? "" : x.Properties["mail"][0].ToString())));
      Array.ForEach(roleUsers, x => AzManResults.Add(x.ToString()));
    }

    public void GetAppMembers()
    {
      string[] roleAppMembers = AzManOperationHelper.AppMembersInRole(RoleName);
      AzManResults.Clear();
      Array.ForEach(roleAppMembers, x => AzManResults.Add(x));
    }

    public void UpdateCache()
    {
      AzManOperationHelper.UpdateCache();
    }

    public event PropertyChangedEventHandler PropertyChanged;

    private void NotifyOfPropertyChange(string propertyName)
    {
      var handler = PropertyChanged;
      if (handler != null)
      {
        handler(this, new PropertyChangedEventArgs(propertyName));
      }
    }
  }
}